package com.sugon.interceptor;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.sugon.annotation.IgnoreAuth;
import com.sugon.entity.ApiResult;
import com.sugon.entity.TokenEntity;
import com.sugon.service.TokenService;
import com.sugon.util.RequestResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 权限(Token)验证
 *
 * @author lipengjun
 * @date 2017年11月20日 下午3:29:40
 */
@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private TokenService tokenService;
    public static final String LOGIN_USER_KEY = "LOGIN_USER_KEY";
    public static final String LOGIN_TOKEN_KEY = "X-Mall-Token";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        IgnoreAuth annotation;
        if (handler instanceof HandlerMethod) {
            annotation = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
        } else {
            return true;
        }
        //如果有@IgnoreAuth注解，则不验证token
        if (annotation != null) {
            return true;
        }
        String token = getToken(request);
        // 校验token是否携带或非法
        TokenEntity tokenEntity;
        if (StrUtil.isEmpty(token) || null == (tokenEntity = tokenService.queryByToken(token))) {
            ApiResult<String> result = new ApiResult<>();
            result.unauthorized();
            RequestResponseUtil.responseWrite(JSON.toJSONString(result), response);
            return false;
        }
        // 校验token是否已失效
        if (tokenEntity.getExpireTime().getTime() < System.currentTimeMillis()) {
            ApiResult<String> result = new ApiResult<>();
            result.invalid();
            RequestResponseUtil.responseWrite(JSON.toJSONString(result), response);
            return false;
        }

        // 刷新token过期时间
        tokenService.refreshTokenExpireTime(tokenEntity);

        //设置userId到request里，后续根据userId，获取用户信息
        request.setAttribute(LOGIN_USER_KEY, tokenEntity.getUserId());
        return true;
    }

    /**
     * 从请求中获取
     * 首先从请求头中获取，如果没有则从请求参数中获取
     */
    private String getToken(HttpServletRequest request) {
        //从header中获取token
        String token = request.getHeader(LOGIN_TOKEN_KEY);
        //如果header中不存在token，则从参数中获取token
        if (StrUtil.isEmpty(token)) {
            token = request.getParameter(LOGIN_TOKEN_KEY);
        }
        return token;
    }

}
